<template>
  <!-- 添加|修改SPU的解构 -->
  <el-form>
    <el-form-item label="SPU名称">
      <el-input
        placeholder="请你输入SPU名称"
        v-model="spuParams.spuName"
      ></el-input>
    </el-form-item>
    <el-form-item label="SPU品牌">
      <el-select placeholder="请选择" v-model="spuParams.tmId">
        <el-option
          :label="trademark.tmName"
          :value="trademark.id"
          v-for="(trademark, index) in allTradeMarkArr"
          :key="trademark.id"
        ></el-option>
      </el-select>
    </el-form-item>
    <el-form-item label="SPU描述">
      <el-input type="textarea" v-model="spuParams.description"></el-input>
    </el-form-item>
    <el-form-item label="SPU图片">
      <!--照片墙人家需要数据:数组+对象{name:'xxx',url:'xxx'}--->
      <!--
         v-model:file-list:照片墙展示数据属性
          action:上传图片的地址
          on-preview:预览按钮的事件回调
          on-remove:删除的事件的回调
      -->
      <el-upload
        :file-list="imgListArr"
        action="/api/admin/product/fileUpload"
        list-type="picture-card"
        :on-preview="handlePictureCardPreview"
        :on-remove="handleRemove"
        :on-success="handleSuccess"
      >
        <el-icon><Plus /></el-icon>
      </el-upload>

      <el-dialog v-model="dialogVisible">
        <img
          :src="dialogImageUrl"
          alt="Preview Image"
          style="width: 400px; height: 400px; margin: 0 auto; display: block"
        />
      </el-dialog>
    </el-form-item>
    <el-form-item label="销售属性">
      <el-select
        v-model="unSaleAttrIdAndName"
        :placeholder="
          unSelectSaleAttr.length > 0
            ? `您还有${unSelectSaleAttr.length}未选择`
            : `没得选啦`
        "
      >
        <el-option
          :label="sale.name"
          :value="`${sale.id}:${sale.name}`"
          v-for="(sale, index) in unSelectSaleAttr"
          :key="sale.id"
        ></el-option>
      </el-select>
      <el-button
        style="margin-left: 10px"
        type="primary"
        size="default"
        :icon="Plus"
        :disabled="!unSaleAttrIdAndName"
        @click="addSaleAttr"
        >添加销售属性值</el-button
      >
      <!-- 展示销售属性与属性值地方 -->
      <el-table style="margin: 10px 0px" :data="spuHasSaleAttrArr">
        <el-table-column
          label="序号"
          type="index"
          align="center"
          width="80"
        ></el-table-column>
        <el-table-column
          label="属性名"
          width="120"
          prop="saleAttrName"
        ></el-table-column>
        <el-table-column label="属性值名称列表">
          <!-- 底下的row:销售属性对象 -->
          <template #="{ row, $index }">
            <!-- 利用el-tag展示销售属性值 -->
            <el-tag
              style="margin: 2px 5px"
              v-for="(saleValue, index) in row.spuSaleAttrValueList"
              :key="saleValue.id"
              class="mx-1"
              closable
              @close="row.spuSaleAttrValueList.splice(index, 1)"
              :type="saleValue.id % 2 == 0 ? 'success' : 'warning'"
            >
              {{ saleValue.saleAttrValueName }}
            </el-tag>
            <!-- button与input的切换:编辑模式与查看模式切换 -->
            <el-input
              v-if="row.flag"
              placeholder="请你输入属性值"
              size="small"
              style="width: 100px"
              @blur="toLook(row)"
              v-model="row.inputValue"
            ></el-input>
            <el-button
              v-else
              type="primary"
              size="small"
              :icon="Plus"
              @click="toEdit(row)"
            ></el-button>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="120">
          <template #="{ row, $index }">
            <el-button
              type="danger"
              size="small"
              :icon="Delete"
              @click="spuHasSaleAttrArr.splice($index, 1)"
            ></el-button>
          </template>
        </el-table-column>
      </el-table>

      <el-button type="primary" size="default" @click="save">保存</el-button>
      <el-button size="default" @click="cancel">取消</el-button>
    </el-form-item>
  </el-form>
</template>
<script setup lang="ts">
//引入组合式API|icon图标|数据类型
import { ref, computed } from "vue";
import { Plus, Delete } from "@element-plus/icons-vue";
import type { UploadProps, UploadUserFile } from "element-plus";
import { ElMessage } from "element-plus";
//引入请求函数
import {
  reqAllaTradeMark,
  reqAllSaleAttr,
  reqImgList,
  reqSpuHasSaleAttr,
  reqAddOrUpdateSpu,
} from "../../../api/product/spu/spu";
//存储相应服务器返回的数据---四个数组
//定义将来添加SPU|修改SPU需要携带给服务器参数
let spuParams = ref<any>({});
//已有SPU下的全部品牌数据
let allTradeMarkArr = ref([]);
//获取已有SPU下照片墙的数据
let imgListArr = ref([]);

//获取已有SPU，拥有销售属性
let spuHasSaleAttrArr = ref([]);
//获取全部销售属性[不管任何SPU销售属性最多三个]
let allSaleAttrArr = ref([]);
//照片墙相关的代码
//存储预览图片地址
const dialogImageUrl = ref("");
//控制对话框显示与隐藏
const dialogVisible = ref(false);

//收集SPU还未选择销售属性ID与名字
let unSaleAttrIdAndName = ref("");

//删除图片回调
const handleRemove: UploadProps["onRemove"] = (uploadFile, uploadFiles) => {
  //第一个参数:uploadFile,删除掉的图片信息  第二个参数:uploadFiles删除完毕剩下图片的信息
  imgListArr.value = uploadFiles;
};
//预览回调
const handlePictureCardPreview: UploadProps["onPreview"] = (uploadFile) => {
  //存储当前用户预览图片地址
  dialogImageUrl.value = uploadFile.url!;
  //展示对话框
  dialogVisible.value = true;
};

//图片上传成功的回调
const handleSuccess = (response, uploadFile, uploadFiles) => {
  //前两个参数:图片上传成功的信息
  //最后的参数:图片上传成功以后，照片墙全部图片数据
  imgListArr.value = uploadFiles;
};

//提供一个方法:将来父组件可以借用的方法
const initHasSpuData = async (spu) => {
  //父组件:传递过来已有SPU信息存储
  spuParams.value = spu;
  //在父组件点击修改SPU按钮的时候，触发子组件当前方法，向服务器发四个请求
  //获取全部品牌数据
  let ps1 = reqAllaTradeMark();
  //获取已有SPU照片墙的数据
  let ps2 = reqImgList(spu.id);
  //获取当前SPU已有销售属性
  let ps3 = reqSpuHasSaleAttr(spu.id);
  //获取全部销售属性
  let ps4 = reqAllSaleAttr();
  //获取全部服务器返回数据
  let result = await Promise.all([ps1, ps2, ps3, ps4]);
  //存储全部品牌
  allTradeMarkArr.value = result[0];
  //存储照片墙的数据
  //由于服务器返回的数据格式并非人家照片墙需要的需要[对象K不符合]
  //当服务器数据返回需要对数据进行处理
  imgListArr.value = result[1].map((item) => {
    return {
      name: item.imgName,
      url: item.imgUrl,
    };
  });
  //存储已有销售属性
  spuHasSaleAttrArr.value = result[2];
  //获取全部销售属性
  allSaleAttrArr.value = result[3];
};

//计算出当前SPU,还没有选择销售属性

let unSelectSaleAttr = computed(() => {
  //外层数组:三个元素  版本、尺码、颜色  -->需要把版本、尺码过滤出来
  let result = allSaleAttrArr.value.filter((item) => {
    //filter回调函数需要返回布尔值:真、代表过滤出来 false：代表新的数组不要
    //数组里面目前:颜色
    return spuHasSaleAttrArr.value.every((item1) => {
      return item.name != item1.saleAttrName;
    });
  });

  return result;
});

//点击添加销售属性按钮回调
const addSaleAttr = () => {
  //整理参数
  //新增的销售属性ID与名字
  const [baseSaleAttrId, saleAttrName] = unSaleAttrIdAndName.value.split(":");
  //服务器需要销售属性对象
  let newSaleAttr = { baseSaleAttrId, saleAttrName, spuSaleAttrValueList: [] };
  //向SPU已有的数组里面追加新增销售是属性
  spuHasSaleAttrArr.value.push(newSaleAttr);
  //清空下拉框的数据
  unSaleAttrIdAndName.value = "";
};

//点击按钮变为编辑模式
const toEdit = (row) => {
  //动态追加flag属性
  //Proxy对象:动态追加的属性也是相应式的
  row.flag = true;
  //追加一个属性：收集销售属性值---有一个起始数值 空串
  row.inputValue = "";
};

//表单元素input失却焦点的事件回调
//row:即为当前销售属性
const toLook = (row) => {
  //属性值非法的情况判断
  console.log(row.inputValue);
  //收集属性值为空
  if (row.inputValue.trim() == "") {
    ElMessage({
      type: "error",
      message: "属性值不能为空",
    });
    return;
  }

  //收集属性值不能与前面已有属性值重复
  let repeat = row.spuSaleAttrValueList.find((item) => {
    //item:已有的销售属性值对象      row.inputValue 新增属性值名称
    return item.saleAttrValueName === row.inputValue;
  });
  //如果出现重复属性值后面的代码不能执行
  if (repeat) {
    ElMessage({
      type: "error",
      message: "属性值名称不能重复",
    });
    //清空最新收集同名属性值
    row.inputValue = "";
    //如果出现同名的属性值显示button
    row.flag = false;
    return;
  }

  //显示button设置
  row.flag = false;
  //新增属性值
  let newSaleattrVal = {
    baseSaleAttrId: row.baseSaleAttrId,
    saleAttrValueName: row.inputValue,
  };
  //追加到当前销售属性值的数组里面
  row.spuSaleAttrValueList.push(newSaleattrVal);
  //清空收集属性值数据
  row.inputValue = "";
};

//按钮保存的事件回调
const save = async () => {
  //整理参数
  //整理照片墙的数据
  spuParams.value.spuImageList = imgListArr.value.map((item) => {
    return {
      imgName: item.name,
      imgUrl: (item.response && item.response.data) || item.url,
    };
  });
  //整理销售属性的参数
  spuParams.value.spuSaleAttrList = spuHasSaleAttrArr.value;
  //发请求:修改|添加
  try {
    await reqAddOrUpdateSpu(spuParams.value);
    ElMessage({
      type: "success",
      message: spuParams.value.id ? "修改成功" : "添加成功",
    });
    //触发自定义事件
    emit("changeScene", {
      scenes: 0,
      flag: spuParams.value.id ? "update" : "add",
    });
    //清空数据
    resetData();
  } catch (error) {
    ElMessage({
      type: "error",
      message: spuParams.value.id ? "修改失败" : "添加失败",
    });
  }

  //触发自定义事件通知父组件切换场景0
};

//取消
const cancel = () => {
  emit("changeScene", {
    scenes: 0,
    flag: spuParams.value.id ? "update" : "add",
  });
  resetData();
};

//清空数据
const resetData = () => {
  spuParams.value = {};
  imgListArr.value = [];
  spuHasSaleAttrArr.value = [];
};

//点击添加SPU的时候，当前子组件发请求(两个:获取全部品牌|全部销售属性)
const initAddSpu = async (c3Id: string | number) => {
  //添加SPU追加三级分类ID
  spuParams.value.category3Id = c3Id;
  //获取全部品牌数据
  let ps1 = reqAllaTradeMark();
  //获取全部销售属性
  let ps2 = reqAllSaleAttr();
  let result = await Promise.all([ps1, ps2]);
  //存储全部品牌
  allTradeMarkArr.value = result[0];
  //获取全部销售属性
  allSaleAttrArr.value = result[1];
};

//触发自定义事件
let emit = defineEmits(["changeScene"]);
//对外暴露方法
defineExpose({
  initHasSpuData,
  initAddSpu,
});
</script>

<style scoped>
</style>


